﻿using System;
using System.Xml.Serialization;
using System.Collections.Generic;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Storage;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Net;

namespace Spacer {
	/*public class PlayerSaveState {
		public PlayerSaveState() {}

		public PlayerSaveState( PlayerController player ) {
			Controller = player;
			Name = player.ControllingGamerName;
			System = (player.CurrentSystem != null ? player.CurrentSystem.ID : Guid.Empty);
			ShipState = (player.CurrentShip != null ? new EntitySaveState(player.CurrentShip) : null);
			if( ShipState != null )
				ShipState.EntityID = Guid.Empty;
		}

		// ----------

		[XmlIgnore]public PlayerController Controller { get; set; }
		
		public string Name { get; set; }
		public Guid System { get; set; }
		public EntitySaveState ShipState { get; set; }
	}*/

	// ----------

	public class PlayerController {
		private static HashSet<PlayerController> s_Players = new HashSet<PlayerController>();
		public static HashSet<PlayerController> Players { get { return s_Players; } }
		
		// ----------

		public static void RemoveController( PlayerController controller ) {
			if( controller.CurrentShip != null )
				controller.CurrentShip.Remove();
			s_Players.Remove( controller );
		}

		public static void RemoveController( NetworkGamer gamer ) {
			foreach(PlayerController controller in s_Players) {
				if( controller.ControllingGamer == gamer ) {
					if( controller.CurrentShip != null )
						controller.CurrentShip.Remove();
					s_Players.Remove( controller );
					break;
				}
			}
		}

		// ----------

		public PlayerController() {
			m_strGamerName = "Player";

			// Store controller
			s_Players.Add( this );
		}

		public PlayerController( NetworkGamer gamer ) {
			// Store which physical controller number is used by this player
			m_strGamerName = "Player";
			ControllingGamer = gamer;
			
			// Store controller
			s_Players.Add( this );
		}

		// ----------

		public void Possess( Ship pawn ) {
			if( !(pawn is Ship) )
				return;

			if( pawn.ControllingPlayer != null )
				pawn.ControllingPlayer.CurrentShip = null;
			
			CurrentShip = pawn;
			pawn.ControllingPlayer = this;
		}

		public void UnPossess() {
			if( CurrentShip == null )
				return;
			
			CurrentShip.ControllingPlayer = null;
			CurrentShip = null;
		}

		// ----------
		
		private Ship m_CurrentShip;
		private SolarSys m_CurrentSystem;
		private string m_strGamerName;
		private EntitySaveState m_ShipState;

		[XmlIgnore]public NetworkGamer ControllingGamer { get; set; }

		[XmlIgnore]public PlayerIndex ControllingIndex {
			get {
				if( ControllingGamer == null || ControllingGamer.IsLocal )
					return PlayerIndex.One;
				else
					return PlayerIndex.Four; // Just a bogus player index until networking is fully done.
			}
		}
		
		[XmlIgnore]public SolarSys CurrentSystem {
			get { return m_CurrentSystem; }
			set {
				if( value != m_CurrentSystem )
					LastSystem = m_CurrentSystem;
				m_CurrentSystem = value;
			}
		}
		[XmlIgnore]public SolarSys LastSystem { get; set; }

		[XmlIgnore]public Type CurrentShipType { get; set; } // Needed incase there is no saved ship state

		[XmlIgnore]public Ship CurrentShip {
			get { return m_CurrentShip; }
			set {
				if( value == null && m_CurrentShip != null ) {
					m_ShipState = new EntitySaveState( CurrentShip );
					m_ShipState.EntityID = Guid.Empty;
				}
				m_CurrentShip = value;
			}
		}

		[XmlIgnore]public UserCommand Input { get { return Spacer.Input.GetUserCmd(ControllingIndex); } }
		
		// ----------

		[XmlElement("GamerName")]
		public string ControllingGamerName {
			get {
				if( !Globals.GamerServicesEnabled )
					return m_strGamerName;
				return ControllingGamer.Gamertag;
			}
			set {
				if( !Globals.GamerServicesEnabled )
					m_strGamerName = value;
			}
		}

		[XmlElement("SystemID")]
		public Guid CurrentSystemID { get; set; }
		/*public Guid CurrentSystemID {
			get { return (CurrentSystem != null ? CurrentSystem.ID : Guid.Empty); }
			set {
				if( Globals.CurrentSession.Galaxy.Systems.ContainsKey(value) )
					CurrentSystem = Globals.CurrentSession.Galaxy.Systems[value];
				else
					CurrentSystem = null;
			}
		}*/


		[XmlElement("ShipState")]
		public EntitySaveState SavedShipState {
			get {
				// Recreate when the CurrentShip exists for saving and transferring between systems
				if( CurrentShip != null ) {
					m_ShipState = new EntitySaveState( CurrentShip );
					m_ShipState.EntityID = Guid.Empty;
				}
				return m_ShipState;
			}
			set {
				m_ShipState = value;
				CurrentShipType = value.EntityType;
			}
		}
	}
}
